package com.lion.common.spring.enhancers;

import com.chris.dev.base.libs.v1.http.protocols.HttpResult;
import com.lion.common.base.exceptions.CommonException;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.sql.SQLException;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Chris Chan
 * Create On 2025/7/28 下午8:13
 * Use for: 全局异常处理
 * Explain:
 */
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 处理自定义异常
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(CommonException.class)
    public HttpResult<?> handleCommonException(CommonException ex) {
        ex.printStackTrace();
        return HttpResult.fail(ex.getCode(), ex.getMessage());
    }

    /**
     * 处理方法参数校验异常
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public HttpResult<?> handleMethodArgumentNotValidException(MethodArgumentNotValidException ex) {
        List<ObjectError> allErrors = ex.getBindingResult().getAllErrors();
        List<String> messageList = allErrors.stream()
                .map(ObjectError::getDefaultMessage)
                .collect(Collectors.toList());
        StringBuilder sb = new StringBuilder("参数校验错误:");
        for (int i = 0; i < messageList.size(); i++) {
            sb.append(i + 1).append(". ").append(messageList.get(i));
            if (i < messageList.size() - 1) {
                sb.append(";");
            }
        }
        sb.append("。 请检查参数。");
//        return HttpResult.create(500, "接口参数校验错误", messageList);
        return HttpResult.fail(500, sb.toString());
    }

    /**
     * SQLException
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(SQLException.class)
    public HttpResult<?> handleSQLException(SQLException ex) {
        ex.printStackTrace();
        return HttpResult.fail(500, "数据库异常");
    }

    /**
     * AccessDeniedException
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(AccessDeniedException.class)
    public HttpResult<?> handleAccessDeniedException(AccessDeniedException ex) {
        return HttpResult.fail(403, "权限不足");
    }

    /**
     * 处理运行时异常
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(RuntimeException.class)
    public HttpResult<?> handleRuntimeException(RuntimeException ex) {
        if (ex instanceof CommonException e) {
            return handleCommonException(e);
        }

        ex.printStackTrace();
        return HttpResult.fail(500, "系统异常");
    }

    /**
     * 处理其他异常
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(Exception.class)
    public HttpResult<?> handleException(Exception ex) {
        if (ex instanceof CommonException e) {
            return handleCommonException(e);
        }
        if (ex instanceof MethodArgumentNotValidException e) {
            return handleMethodArgumentNotValidException(e);
        }
        if (ex instanceof SQLException e) {
            return handleSQLException(e);
        }
        if (ex instanceof RuntimeException e) {
            return handleRuntimeException(e);
        }
        ex.printStackTrace();
        return HttpResult.fail(500, "系统异常");
    }


}
